Disk+[Data].swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import Foundation
  2. public extension Disk {
  3. /// Save an array of Data objects to disk
  4. ///
  5. /// - Parameters:
  6. /// - value: array of Data to store to disk
  7. /// - directory: user directory to store the files in
  8. /// - path: folder location to store the data files (i.e. "Folder/")
  9. /// - Throws: Error if there were any issues creating a folder and writing the given [Data] to files in it
  10. static func save(_ value: [Data], to directory: Directory, as path: String) throws {
  11. do {
  12. let folderUrl = try createURL(for: path, in: directory)
  13. try createSubfoldersBeforeCreatingFile(at: folderUrl)
  14. try FileManager.default.createDirectory(at: folderUrl, withIntermediateDirectories: false, attributes: nil)
  15. for i in 0 ..< value.count {
  16. let data = value[i]
  17. let dataName = "\(i)"
  18. let dataUrl = folderUrl.appendingPathComponent(dataName, isDirectory: false)
  19. try data.write(to: dataUrl, options: .atomic)
  20. }
  21. } catch {
  22. throw error
  23. }
  24. }
  25. /// Append a file with Data to a folder
  26. ///
  27. /// - Parameters:
  28. /// - value: Data to store to disk
  29. /// - directory: user directory to store the file in
  30. /// - path: folder location to store the data files (i.e. "Folder/")
  31. /// - Throws: Error if there were any issues writing the given data to disk
  32. static func append(_ value: Data, to path: String, in directory: Directory) throws {
  33. do {
  34. if let folderUrl = try? getExistingFileURL(for: path, in: directory) {
  35. let fileUrls = try FileManager.default.contentsOfDirectory(
  36. at: folderUrl,
  37. includingPropertiesForKeys: nil,
  38. options: []
  39. )
  40. var largestFileNameInt = -1
  41. for i in 0 ..< fileUrls.count {
  42. let fileUrl = fileUrls[i]
  43. if let fileNameInt = fileNameInt(fileUrl) {
  44. if fileNameInt > largestFileNameInt {
  45. largestFileNameInt = fileNameInt
  46. }
  47. }
  48. }
  49. let newFileNameInt = largestFileNameInt + 1
  50. let data = value
  51. let dataName = "\(newFileNameInt)"
  52. let dataUrl = folderUrl.appendingPathComponent(dataName, isDirectory: false)
  53. try data.write(to: dataUrl, options: .atomic)
  54. } else {
  55. let array = [value]
  56. try save(array, to: directory, as: path)
  57. }
  58. } catch {
  59. throw error
  60. }
  61. }
  62. /// Append an array of data objects as files to a folder
  63. ///
  64. /// - Parameters:
  65. /// - value: array of Data to store to disk
  66. /// - directory: user directory to create folder with data objects
  67. /// - path: folder location to store the data files (i.e. "Folder/")
  68. /// - Throws: Error if there were any issues writing the given Data
  69. static func append(_ value: [Data], to path: String, in directory: Directory) throws {
  70. do {
  71. if let _ = try? getExistingFileURL(for: path, in: directory) {
  72. for data in value {
  73. try append(data, to: path, in: directory)
  74. }
  75. } else {
  76. try save(value, to: directory, as: path)
  77. }
  78. } catch {
  79. throw error
  80. }
  81. }
  82. /// Retrieve an array of Data objects from disk
  83. ///
  84. /// - Parameters:
  85. /// - path: path of folder that's holding the Data objects' files
  86. /// - directory: user directory where folder was created for holding Data objects
  87. /// - type: here for Swifty generics magic, use [Data].self
  88. /// - Returns: [Data] from disk
  89. /// - Throws: Error if there were any issues retrieving the specified folder of files
  90. static func retrieve(_ path: String, from directory: Directory, as _: [Data].Type) throws -> [Data] {
  91. do {
  92. let url = try getExistingFileURL(for: path, in: directory)
  93. let fileUrls = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [])
  94. let sortedFileUrls = fileUrls.sorted(by: { (url1, url2) -> Bool in
  95. if let fileNameInt1 = fileNameInt(url1), let fileNameInt2 = fileNameInt(url2) {
  96. return fileNameInt1 <= fileNameInt2
  97. }
  98. return true
  99. })
  100. var dataObjects = [Data]()
  101. for i in 0 ..< sortedFileUrls.count {
  102. let fileUrl = sortedFileUrls[i]
  103. let data = try Data(contentsOf: fileUrl)
  104. dataObjects.append(data)
  105. }
  106. return dataObjects
  107. } catch {
  108. throw error
  109. }
  110. }
  111. }